package com.spzx.cart.service.impl;

import com.alibaba.nacos.common.utils.CollectionUtils;
import com.spzx.cart.api.domain.CartInfo;
import com.spzx.cart.service.ICartService;
import com.spzx.common.core.constant.SecurityConstants;
import com.spzx.common.core.context.SecurityContextHolder;
import com.spzx.common.core.domain.R;
import com.spzx.common.core.exception.ServiceException;
import com.spzx.product.api.RemoteProductService;
import com.spzx.product.api.domain.ProductSku;
import com.spzx.product.api.domain.vo.SkuPrice;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 添加购物车Service
 */
@Service
public class CartServiceImpl implements ICartService {

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    RemoteProductService remoteProductService;

    private String getCartKey(Long userId) {
        return "user:cart:" + userId;
    }

    /**
     * 添加购物车
     *
     * @param skuId  商品SkuId
     * @param skuNum Sku数量
     */
    @Override
    public void addToCart(Long skuId, Integer skuNum) {
        //获取当前登录的用户id
        Long userId = SecurityContextHolder.getUserId();
        //1.构建用户购物车hash结构key
        String cartKey = getCartKey(userId);

        //2.创建Hash结构绑定操作对象
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);

        String hashKey = skuId.toString();
        Integer threshold = 99;
        //4.判断用户购物车中是否包含该商品 如果包含：数量进行累加(某件商品数量上限99) 不包含：新增购物车商品
        if (hashOps.hasKey(hashKey)) {
            //4.1 说明该商品在购物车中已有，对数量进行累加 ，不能超过指定上限99
            CartInfo cartInfo = hashOps.get(hashKey);
            int totalCount = cartInfo.getSkuNum() + skuNum;
            cartInfo.setSkuNum(totalCount > threshold ? threshold : totalCount);
            hashOps.put(hashKey, cartInfo);
        } else {
            //3.判断购物车商品种类（不同SKU）总数大于50件
            if (hashOps.size() >= 50) {
                throw new ServiceException("商品种类数量超过上限");
            }
            //4. 说明购物车没有该商品，构建购物车对象，存入Redis
            CartInfo cartInfo = new CartInfo();
            cartInfo.setUserId(userId);
            cartInfo.setSkuNum(skuNum > threshold ? threshold : skuNum);
            cartInfo.setUpdateTime(new Date());
            cartInfo.setCreateTime(new Date());
            //4.2 远程调用商品服务获取商品实时价格
            R<ProductSku> productSkuResult = remoteProductService.getProductSku(skuId, SecurityConstants.INNER);
            if (R.FAIL == productSkuResult.getCode()) {
                throw new ServiceException(productSkuResult.getMsg());
            }
            ProductSku productSku = productSkuResult.getData();
            cartInfo.setSkuId(productSku.getId());
            cartInfo.setSkuName(productSku.getSkuName());
            cartInfo.setThumbImg(productSku.getThumbImg());
            cartInfo.setSkuPrice(productSku.getSalePrice());
            cartInfo.setCartPrice(productSku.getSalePrice());

            //4.3 将购物车商品存入Redis
            hashOps.put(hashKey, cartInfo);
        }
    }

    /**
     * 查看购物车
     *
     * @return 购物车列表
     */
    @Override
    public List<CartInfo> getCartList() {
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);

        List<CartInfo> cartInfoList = hashOps.values();
        if (CollectionUtils.isNotEmpty(cartInfoList)) {
            //排序
            cartInfoList = cartInfoList.stream().sorted((o1, o2) -> o2.getCreateTime().compareTo(o2.getCreateTime())).toList();
            //获取skuId列表
            List<Long> skuIdList = cartInfoList.stream().map(CartInfo::getSkuId).toList();
            R<List<SkuPrice>> skuPriceListResult = remoteProductService.getSkuPriceList(skuIdList, SecurityConstants.INNER);
            if (R.FAIL == skuPriceListResult.getCode()) {
                throw new ServiceException(skuPriceListResult.getMsg());
            }
            List<SkuPrice> skuPriceList = skuPriceListResult.getData();
            Map<Long, BigDecimal> skuIdToSalePriceMap = skuPriceList.stream().collect(Collectors.toMap(SkuPrice::getSkuId, SkuPrice::getSalePrice));
            for (CartInfo cartInfo : cartInfoList) {
                BigDecimal salePrice = skuIdToSalePriceMap.get(cartInfo.getSkuId());
                cartInfo.setSkuPrice(salePrice);
            }
            return cartInfoList;
        }


        return new ArrayList<>();
    }

    /**
     * 删除购物车
     *
     * @param skuId skuId
     */
    @Override
    public void deleteCart(Long skuId) {
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);
        BoundHashOperations hashOps = redisTemplate.boundHashOps(cartKey);
        hashOps.delete(skuId.toString());
    }

    /**
     * 更新选中状态
     *
     * @param skuId     skuId
     * @param isChecked 选中状态
     */
    @Override
    public void checkCart(Long skuId, Integer isChecked) {
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        if (hashOps.hasKey(skuId.toString())) {
            CartInfo cartInfo = hashOps.get(skuId.toString());
            cartInfo.setIsChecked(isChecked);
            hashOps.put(skuId.toString(), cartInfo);
        }
    }

    /**
     * 更新购物车商品全部选中状态
     *
     * @param isChecked 选中状态
     */
    @Override
    public void allCheckCart(Integer isChecked) {
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = hashOps.values();
        for (CartInfo cartInfo : cartInfoList) {
            CartInfo cartInfo1 = hashOps.get(cartInfo.getSkuId().toString());
            cartInfo1.setIsChecked(isChecked);
            hashOps.put(cartInfo.getSkuId().toString(), cartInfo1);
        }
    }

    /**
     * 清空购物车
     */
    @Override
    public void clearCart() {
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);
        redisTemplate.delete(cartKey);
    }

    /**
     * 查询用户购物车列表中选中商品列表
     *
     * @param userId 用户id
     * @return 选中的商品列表
     */
    @Override
    public List<CartInfo> getCartCheckedList(Long userId) {
        List<CartInfo> cartCachInfoList = new ArrayList<>();

        String cartKey = getCartKey(userId);
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = hashOps.values();

        if (CollectionUtils.isNotEmpty(cartInfoList)) {
            for (CartInfo cartInfo : cartInfoList) {
                if (cartInfo.getIsChecked() == 1) {
                    cartCachInfoList.add(cartInfo);
                }
            }
        }
        return cartCachInfoList;
    }

    /**
     * 更新用户购物车列表价格
     * @param userId 用户id
     * @return 返回是否更新成功
     */
    @Override
    public Boolean updateCartPrice(Long userId) {
        String cartKey = getCartKey(userId);
        BoundHashOperations<String,String,CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = hashOps.values();
        if (CollectionUtils.isNotEmpty(cartInfoList)){
            for (CartInfo cartInfo : cartInfoList) {
                if (cartInfo.getIsChecked().intValue() == 1){
                    SkuPrice skuPrice = remoteProductService.getSkuPrice(cartInfo.getSkuId(), SecurityConstants.INNER).getData();
                    cartInfo.setCartPrice(skuPrice.getSalePrice());
                    cartInfo.setSkuPrice(skuPrice.getSalePrice());
                    hashOps.put(cartInfo.getSkuId().toString(),cartInfo);
                }
            }
        }
        return true;
    }

    /**
     * 删除用户购物车列表中选中商品列表
     * @param userId 用户id
     * @return 返回结果
     */
    @Override
    public Boolean deleteCartCheckedList(Long userId) {
        String cartKey = getCartKey(userId);
        BoundHashOperations<String,String,CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = hashOps.values();
        if (CollectionUtils.isNotEmpty(cartInfoList)){
            for (CartInfo cartInfo : cartInfoList) {
                if (cartInfo.getIsChecked().intValue() == 1){
                    hashOps.delete(cartInfo.getSkuId().toString());
                }
            }
        }
        return true;
    }
}
